package persistence;

import java.util.ArrayList;
import java.util.List;

import docks.Dock;

import utils.DataDownloader;
import utils.ShowException;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DataBaseAPIImpl implements DataBaseAPI {

    private DataBaseHelper dbh;
    private Cursor gBicingCursor = null;
    private SQLiteDatabase db;
    private Context ctx;

    public DataBaseAPIImpl(Context ctx) {

	this.ctx = ctx;
	dbh = new DataBaseHelper(ctx, "gBicingDB");

//	Log.v("CHIVATO", "Ara anem a baixar els valors d'internet");
//
//	try {
//
//	    for (Dock d : DataDownloader.download().values()) {
//
//		if (d.getIdDock() != 0) {
//
//		    Log.v("CHIVATO", "Afegint Dock: " + d.getIdDock() + "!!!!!");
//		    insertDock(d);
//		}
//	    }
//
//	} catch (Exception e) {
//	    // TODO Auto-generated catch block
//	    e.printStackTrace();
//	}
    }

    @Override
    public long insertFavorite(int id) {

	ContentValues values = new ContentValues(1);
	values.put("starred", 1);
	Log.v("CHIVATO", "Insertando favorito LALALALALALA");
	db = dbh.getWritableDatabase();
	String[] args = { String.valueOf(id) };
	return db.update("docks", values, "_id=?", args);
    }

    @Override
    public long deleteFavorite(int id) {

	ContentValues values = new ContentValues(1);
	values.put("starred", 0);

	db = dbh.getWritableDatabase();
	String[] args = { String.valueOf(id) };
	return db.update("docks", values, "_id=?", args);
    }

    public void onDestroy() {

	gBicingCursor.close();
	db.close();
    }

    @Override
    public List<Dock> getFavorites() {

	List<Dock> starredList = null;

	try {
	    String[] args = { String.valueOf(1) };
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " " + "WHERE starred=?"
			    + " " + "ORDER BY _id", args);

	    starredList = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return starredList;
    }

    @Override
    public List<Dock> getAll() {
	List<Dock> alldocks = null;
	try {
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " " + "ORDER BY _id",
		    null);

	    alldocks = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return alldocks;
    }

    @Override
    public List<Dock> getFull() {
	List<Dock> fulldocks = null;
	try {
	    String[] args = { String.valueOf(0), String.valueOf(0) };
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " "
			    + "WHERE freeslots=? AND available!=?" + " "
			    + "ORDER BY _id", args);

	    fulldocks = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return fulldocks;
    }

    @Override
    public List<Dock> getHalf() {
	List<Dock> halfdocks = null;
	try {
	    String[] args = { String.valueOf(0), String.valueOf(0) };
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " "
			    + "WHERE freeslots!=? AND available!=?" + " "
			    + "ORDER BY _id", args);

	    halfdocks = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return halfdocks;
    }

    @Override
    public List<Dock> getEmpty() {
	List<Dock> emptydocks = null;
	try {
	    String[] args = { String.valueOf(0), String.valueOf(0) };
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " "
			    + "WHERE freeslots!=? AND available=?" + " "
			    + "ORDER BY _id", args);

	    emptydocks = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return emptydocks;
    }

    @Override
    public synchronized long insertDock(Dock d) {

	ContentValues values = new ContentValues();
	values.put("_id", d.getIdDock());
	values.put("address", d.getAddress());
	values.put("freeslots", d.getFreeSlots());
	values.put("available", d.getAvailableBikes());
	values.put("latitude", d.getLatitude());
	values.put("longitude", d.getLongitude());
	values.put("starred", 0);

	db = dbh.getWritableDatabase();
	return db.insert("docks", null, values);
    }

    @Override
    public long updateDock(int id, int free, int available) {

	ContentValues values = new ContentValues();
	values.put("freeslots", free);
	values.put("available", available);
	db = dbh.getWritableDatabase();
	String[] args = { String.valueOf(id) };
	return db.update("docks", values, "_id=?", args);
    }

    @Override
    public Dock getDock(int id) {

	Dock current;
	int _id;
	String address;
	int freeslots;
	int available;
	double latitude;
	double longitude;
	boolean starred;
	String[] args = { String.valueOf(id) };
	db = dbh.getReadableDatabase();
	Cursor c = db.rawQuery(
		"SELECT _id, address, freeslots, available, latitude, longitude, starred"
			+ " " + "FROM docks" + " " + "WHERE _id = ?",
		args);
	c.moveToFirst();

	current = new Dock();

	_id = c.getInt(c.getColumnIndex("_id"));
	address = c.getString(c.getColumnIndex("address"));
	freeslots = c.getInt(c.getColumnIndex("freeslots"));
	available = c.getInt(c.getColumnIndex("available"));
	latitude = c.getDouble(c.getColumnIndex("latitude"));
	longitude = c.getDouble(c.getColumnIndex("longitude"));
	starred = c.getInt(c.getColumnIndex("starred")) == 1;

	current.setIdDock(_id);
	current.setAddress(address);
	current.setFreeSlots(freeslots);
	current.setAvailableBikes(available);
	current.setLatitude(latitude);
	current.setLongitude(longitude);
	current.setStarred(starred);

	c.close();

	return current;
    }

    @Override
    public List<Dock> getNotFull() {

	List<Dock> notfulldocks = null;
	try {
	    String[] args = { String.valueOf(0)};
	    db = dbh.getReadableDatabase();
	    gBicingCursor = db.rawQuery(
		    "SELECT _id, address, freeslots, available, latitude, longitude, starred"
			    + " " + "FROM docks" + " "
			    + "WHERE freeslots!=?" + " "
			    + "ORDER BY _id", args);

	    notfulldocks = getCursorInfo(gBicingCursor);

	} catch (Exception e) {

	    ShowException.show(ctx, e);
	}

	return notfulldocks;
    }

	@Override
	public List<Dock> getNotEmpty() {
		
		List<Dock> notemptydocks = null;
		try{
			String[] args = { String.valueOf(0)};
		    db = dbh.getReadableDatabase();
		    gBicingCursor = db.rawQuery( "SELECT _id, address, freeslots, available, latitude, longitude, starred"
				    + " " + "FROM docks" + " "
				    + "WHERE available!=?" + " "
				    + "ORDER BY _id", args);
		    
		    notemptydocks = getCursorInfo(gBicingCursor);
			
		}catch (Exception e) {
			ShowException.show(ctx, e);
		}
		
		return notemptydocks;
	}
	
	private List<Dock> getCursorInfo(Cursor c) {

		List<Dock> list = new ArrayList<Dock>();
		Dock current;
		int _id;
		String address;
		int freeslots;
		int available;
		double latitude;
		double longitude;
		boolean starred;
		c.moveToFirst();
		while (c.isAfterLast() == false) {

		    current = new Dock();

		    _id = c.getInt(c.getColumnIndex("_id"));
		    address = c.getString(c.getColumnIndex("address"));
		    freeslots = c.getInt(c.getColumnIndex("freeslots"));
		    available = c.getInt(c.getColumnIndex("available"));
		    latitude = c.getDouble(c.getColumnIndex("latitude"));
		    longitude = c.getDouble(c.getColumnIndex("longitude"));
		    starred = c.getInt(c.getColumnIndex("starred")) == 1;

		    current.setIdDock(_id);
		    current.setAddress(address);
		    current.setFreeSlots(freeslots);
		    current.setAvailableBikes(available);
		    current.setLatitude(latitude);
		    current.setLongitude(longitude);
		    current.setStarred(starred);

		    list.add(current);
		    c.moveToNext();
		}
		c.close();

		return list;
	    }

}
